#pragma once

#include <string>
#include <vector>
#include <map>
#include <optional>
#include <nlohmann/json.hpp>
#include <functional>
#include <future>
#include "base_noncopyable.h"

namespace El {
namespace Upgrade {

// 升级包类型
enum class UpgradeType {
    FULL, // 完整包
    DIFF  // 差分包
};

// 文件升级信息
struct FileUpgradeInfo {
    std::string name;       // 文件名
    std::string partition;  // MTD分区设备
    std::string offset;     // 写入偏移
    size_t size;            // 文件大小
    bool verify;            // 是否校验
    std::string hash;       // 文件哈希值
    bool need_update{true}; // 是否需要更新,默认为true
};

// 升级状态
enum class UpgradeStatus {
    IDLE,        // 空闲状态
    DOWNLOADING, // 下载中
    VERIFYING,   // 校验中
    UPGRADING,   // 升级中
    SUCCESS,     // 升级成功
    FAILED,      // 升级失败
    ROLLBACK     // 回滚中
};

// 升级包信息
struct UpgradePackageInfo {
    std::string productName;                    // 产品型号
    std::string hardwareVersion;                // 硬件版本
    std::string fromVersion;                    // 起始版本(差分包必填)
    std::string toVersion;                      // 目标版本
    UpgradeType type;                           // 升级包类型
    std::string minVersion;                     // 最小兼容版本
    std::string maxVersion;                     // 最大兼容版本
    std::vector<FileUpgradeInfo> fileInfos;     // 文件升级信息列表
    std::map<std::string, std::string> scripts; // 升级脚本
};

class Upgrade {
    DISALLOW_COPY_AND_MOVE(Upgrade);

public:
    static Upgrade &GetInstance();

    // 启动升级模块
    bool Start();

    // 关闭升级模块
    void Stop();

    // 设置进度回调函数，参数：progress 进度值, isSuccess 是否成功 (true: 成功, false: 失败)
    void SetProgressCallback(std::function<void(int progress, bool isSuccess)> callback);

    // 升级准备
    bool PrepareUpgrade();

    // 追加升级包数据到内存缓冲区
    bool Append(const uint8_t *data, size_t length);

    // 开始升级过程
    bool StartUpgrade();

    // 开始升级过程 (异步方式，不等待返回结果)
    void StartUpgradeAsync();

    // 获取当前升级状态
    UpgradeStatus GetStatus() const
    {
        return status_;
    }

    // 获取升级进度(0-100)
    int GetProgress() const
    {
        return progress_;
    }

private:
    Upgrade();
    ~Upgrade();

    // 解析升级包
    bool ParseUpgradePackage();

    // 验证升级包
    bool VerifyUpgradePackage();

    // 解析manifest.json
    bool ParseManifest(const std::string &manifestContent);

    // 验证文件完整性
    bool VerifyFileHash(const std::string &filename, const std::string &expectedHash);

    // 执行升级脚本
    bool ExecuteScript(const std::string &script);

private:
    std::vector<uint8_t> buffer_;                              // 内存缓冲区
    UpgradeStatus status_;                                     // 当前状态
    int progress_;                                             // 升级进度
    UpgradePackageInfo packageInfo_;                           // 升级包信息
    std::map<std::string, std::string> files_;                 // 文件列表
    std::function<void(int, bool)> progressCallback_{nullptr}; // 进度回调函数
};

} // namespace Upgrade
} // namespace El
